<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            padding-bottom: 800px;
            padding-left: 30px;
        }
    </style>
</head>
<body>
    <div id="app">
        <h4>计算属性</h4>
        <!-- 
        计算属性：
            + 在vue应用创建中以 computed:{} 进行计算属性定义
            + computed 定义时，对象的key为计算属性名，value 取值 function 用于定义执行过程
            + computed 定义的数据在模板语法中以仓库属性方法进行调用【调用方式等效于仓库变量】【计算属性仓库】
            + computed 定义的数据取值为 function 时，等同于 methods中定义的普通方法，可以通过this调用其它参数数据，并完成逻辑运行
            + computed 定义的数据在页面使用时一样具有响应式规则，计算的关联数据发生变化，于计算属性有关页面元素会重新渲染
            + 计算属性具有数据缓存特性 => 第一次调用属性时会完成方法执行并加载计算结果，通过完成结果缓存
                                         后续在关联数据没有发生变化时再次调用，只会读取缓存结果，不会再执行方法
                                         当关联数据发生变化时，计算属性会重新计算结果，并对新结果进行缓存
            + 计算属性默认为只读属性

        双向计算属性
            + 当计算属性取值为固定对象数据 { get(){},set(){} } 时，将开启计算的双向操作功能
            + 当开启双向操作功能时，如果需要构建具有功能作用的计算属性，需要以data仓库的基础变量作为中间变量

        计算属性的应用
            应用场景1：数据统计 (参考作业 购物车)
            应用场景2：模板语法的 v-model 功能整合 (参考作业 购物车)
            应用场景3：数据过滤 ( select2 带搜索的下拉列表 )
            应用场景4：模板语法逻辑整合
        -->
        <p>nums:{{ nums }}</p>
        <input type="number" v-for="(item,i) in nums" v-model="nums[i]">
        <hr>
        <p>sum:{{ sumFun() }}</p>
        <p>sum:{{ sumFun() }}</p>
        <p>sum:{{ sumFun() }}</p>
        <p>sum:{{ sumFun() }}</p>
        <p>sum:{{ sumFun() }}</p>
        <p>sum:{{ sumFun() }}</p>
        <hr>
        <p>sum:{{ sum }}</p>
        <p>sum:{{ sum }}</p>
        <p>sum:{{ sum }}</p>
        <p>sum:{{ sum }}</p>
        <p>sum:{{ sum }}</p>
        <p>sum:{{ sum }}</p>
        <input type="button" value="修改sum" @click="sum=100">
        <hr>
        <p>text:{{ text }}</p>
        <input type="button" value="修改text" @click="text=100">
        <hr>
        <div>
            <input type="text" v-model="word">
            <ul>
                <li v-for="item in filterArr">{{ item }}</li>
            </ul>
        </div>
        <hr>
        <div>
            <input type="text" v-model="arg">
            <span>{{  res  }}</span>
        </div>
        <input type="button" value="打印vue实例" @click="printThis()">
    </div>
    <script src="../assets/mock/mock-min.js"></script>
    <script type="module">
        // 加载 Vue3 的ESM 模块文件
        import { createApp } from "../assets/vue3/vue.esm-browser.js"
        createApp({
            data(){
                return {
                    nums:[2,3,4,5,6,7],
                    msg:"",
                    _text:"text",
                    word:"",
                    arr:Mock.mock({
                        "arr|20":[
                            "@word"
                        ]
                    }).arr,
                    arg:""
                }
            },
            computed:{
                sum:function(){
                    console.log("执行computed的统计sum")
                    return this.nums.reduce((c,item)=>c+item,0)
                },
                text:{
                    get:function(){
                        console.log("执行computed的text的getter")
                        // return "text"
                        return this._text;
                    },
                    set(nv){
                        console.log("执行computed的text的setter",nv)
                        this._text = nv;
                    }
                },
                filterArr(){
                    return this.arr.filter( item => item.indexOf(this.word)!=-1 )
                },
                res(){
                    if(this.arg==""){
                        return "";
                    }
                    if(isNaN( this.arg*1 )){
                        if( /^[a-zA-z0-9]+@[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)$/.test(this.arg) ){
                            return "邮箱"
                        }
                        return "字符串"
                    }else{
                        if( /^(?:(?:\+|00)86)?1\d{10}$/.test(this.arg) ){
                            return "手机号码"
                        }
                        return "数值"
                    }
                    // 数值|字符串|电话|邮箱 
                }
            },
            methods:{
                sumFun(){
                    console.log("执行methods的统计方法sumFun")
                    /*
                        [2,3,4,5,6,7].reduce(function(count,item,index){
                            return count+item
                        },0)
                    */
                    return this.nums.reduce((c,item)=>c+item,0)
                },
                printThis(){
                    console.log(this);
                }
            }
        }).mount("#app")
    </script>
</body>
</html>